(31337_64897298154598, `[large]Overview[/large]

The [link="Assembly/Language creation"]Language creation[/link] page describes only basic instruction definitions, this page aims to cover more advanced features.

An instruction definition consists of the following lines:

[color=#66ff99]Syntax[/color]
[color=#ffe666]Virtual operands[/color] (optional)
[color=#ff6680]Assertions[/color] (optional)
[color=#66ccff]Machine code[/color]
[color=#9966ff]Description[/color]

Example:
[box][color=#66ff99]jmp %offset(label)[/color]
[color=#ffe666]%high_bits = %offset / 4[/color]
[color=#ff6680]assert(%offset % 4 == 0, "Can only jump to 4 byte aligned addresses")[/color]
[color=#66ccff]01 hhhhhh[/color]
[color=#9966ff]# Jump to %offset[/color][/box]

[large][color=#66ff99]Syntax[/color][/large]
Syntaxes are a list of [b]literals[/b] and [b]operands[/b], seperated by [b]whitespace[/b].

[b]Literals[/b]
In the above example the mnemonic [highlight]jmp[/highlight] is a literal. Instructions with multiple operands typically have operands seperated by [highlight],[/highlight] literals as well.
Use [highlight]%%[/highlight] to escape [highlight]%[/highlight] symbol in literals.

[b]Operands[/b]
Instruction operands start with the [highlight]%[/highlight] prefix and are written in the form [highlight]%name(fields)[/highlight].
* [highlight]name[/highlight] is any identifier. 
* [highlight]fields[/highlight] is a list of one or more fields created in the prior section "Fields" (or the reserved fields). The list is delimited by the pipe ([highlight]|[/highlight]) character.

[b]Whitespace[/b]
Whitespace can be either tabs or spaces. If a single whitespace character is used, the space will be optional in the assembly language. If the whitespace character is instead followed by another space, the assembler will require whitespace between the tokens.


[large][color=#ffe666]Virtual operands[/color][/large]
In the architecture of the jump example above, all instructions are 4 byte wide, so the lower two bits of the jump destination is always supposed to be 0. We can create a new virtual operand without these two lower bits like so:
[box]%high_bits = %offset / 4[/box]
We will use [highlight]%high_bits[/highlight] instead of [highlight]%offset[/highlight] in the machine code definition.
A list of supported operators can be found [link="Assembly/Language creation/Instructions/Operators"]here[/link].

Two special operands are automatically defined, [highlight]$start[/highlight] and [highlight]$end[/highlight]. $start is the offset of the machine code just before the instruction and $end is just after. These can for example be used to calculate offsets relative to the current instruction, like so:
[box]%rel_offset = %offset - $end[/box]

[large][color=#ff6680]Assertions[/color][/large]
Assertions allow you to check for user errors. In the example above, we use them to ensure that we are jumping to a 4 byte aligned address.


[large][color=#66ccff]Machine code[/color][/large]
The example above uses the following machine code syntax.
[box]01 hhhhhh[/box]
Note that [highlight]h[/highlight] refers to the [highlight]%high_bits[/highlight] virtual operand. Using this syntax, bits of operands are always represented by the first letter of their name.

An alternative but equivelent way to write the same thing is using [b]bit slicing[/b] instead:
[box]01 %offset\[8:2][/box]
Bit slicing uses standard hardware syntax for selecting a part of a bit field. The syntax is: [highlight]\[last:first][/highlight] where both first and last are inclusive.

Bit slicing can be used on multiple operands and intermixed with one bit per character syntax.


[large][color=#9966ff]Description[/color][/large]
The description has no function to the assembler, it exists purely for documentation purposes.

`)